<template>
  <el-dialog
    v-model="visible"
    :show-close="false"
    :close-on-click-modal="true"
    :close-on-press-escape="true"
    class="image-viewer-dialog"
    fullscreen
  >
    <div class="image-viewer-container" @click="handleClose">
      <div class="image-viewer-header">
        <div class="image-info">
          <span class="image-title">{{ currentImage.title || '图片预览' }}</span>
          <span class="image-index" v-if="images.length > 1">
            {{ currentIndex + 1 }} / {{ images.length }}
          </span>
        </div>
        
        <div class="image-actions">
          <el-button circle @click.stop="zoomOut" :disabled="scale <= 0.2">
            <el-icon><ZoomOut /></el-icon>
          </el-button>
          <el-button circle @click.stop="resetZoom">
            <el-icon><Refresh /></el-icon>
          </el-button>
          <el-button circle @click.stop="zoomIn" :disabled="scale >= 3">
            <el-icon><ZoomIn /></el-icon>
          </el-button>
          <el-button circle @click.stop="rotateLeft">
            <el-icon><RefreshLeft /></el-icon>
          </el-button>
          <el-button circle @click.stop="rotateRight">
            <el-icon><RefreshRight /></el-icon>
          </el-button>
          <el-button circle @click.stop="downloadImage">
            <el-icon><Download /></el-icon>
          </el-button>
          <el-button circle @click.stop="handleClose">
            <el-icon><Close /></el-icon>
          </el-button>
        </div>
      </div>
      
      <div class="image-viewer-content" @click.stop>
        <!-- 上一张按钮 -->
        <div 
          v-if="images.length > 1" 
          class="nav-button nav-prev"
          @click="prevImage"
        >
          <el-icon><ArrowLeft /></el-icon>
        </div>
        
        <!-- 图片容器 -->
        <div class="image-container" ref="imageContainer">
          <img
            ref="imageRef"
            :src="currentImage.url"
            :alt="currentImage.title"
            :style="imageStyle"
            @load="handleImageLoad"
            @error="handleImageError"
            @mousedown="startDrag"
            draggable="false"
          />
          
          <!-- 加载状态 -->
          <div v-if="loading" class="image-loading">
            <el-icon class="loading-icon"><Loading /></el-icon>
            <span>加载中...</span>
          </div>
          
          <!-- 错误状态 -->
          <div v-if="error" class="image-error">
            <el-icon class="error-icon"><Picture /></el-icon>
            <span>图片加载失败</span>
          </div>
        </div>
        
        <!-- 下一张按钮 -->
        <div 
          v-if="images.length > 1" 
          class="nav-button nav-next"
          @click="nextImage"
        >
          <el-icon><ArrowRight /></el-icon>
        </div>
      </div>
      
      <!-- 缩略图列表 -->
      <div v-if="images.length > 1" class="thumbnail-list">
        <div 
          v-for="(image, index) in images" 
          :key="index"
          class="thumbnail-item"
          :class="{ active: index === currentIndex }"
          @click="setCurrentImage(index)"
        >
          <img :src="image.thumbnail || image.url" :alt="image.title" />
        </div>
      </div>
    </div>
  </el-dialog>
</template>

<script setup>
import { ref, computed, watch, nextTick } from 'vue'
import { 
  ZoomOut, ZoomIn, Refresh, RefreshLeft, RefreshRight, 
  Download, Close, ArrowLeft, ArrowRight, Loading, Picture
} from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'

// Props
const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  images: {
    type: Array,
    default: () => []
  },
  initialIndex: {
    type: Number,
    default: 0
  }
})

// Emits
const emit = defineEmits(['update:modelValue', 'change'])

// 响应式数据
const imageRef = ref()
const imageContainer = ref()
const currentIndex = ref(0)
const scale = ref(1)
const rotation = ref(0)
const translateX = ref(0)
const translateY = ref(0)
const loading = ref(false)
const error = ref(false)
const isDragging = ref(false)
const dragStart = ref({ x: 0, y: 0 })

// 计算属性
const visible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

const currentImage = computed(() => {
  return props.images[currentIndex.value] || { url: '', title: '' }
})

const imageStyle = computed(() => {
  return {
    transform: `scale(${scale.value}) rotate(${rotation.value}deg) translate(${translateX.value}px, ${translateY.value}px)`,
    transition: isDragging.value ? 'none' : 'transform 0.3s ease',
    cursor: isDragging.value ? 'grabbing' : 'grab'
  }
})

// 监听器
watch(() => props.initialIndex, (newIndex) => {
  currentIndex.value = newIndex
}, { immediate: true })

watch(currentIndex, () => {
  resetTransform()
  emit('change', currentIndex.value)
})

watch(visible, (newVisible) => {
  if (newVisible) {
    resetTransform()
    document.addEventListener('keydown', handleKeydown)
  } else {
    document.removeEventListener('keydown', handleKeydown)
  }
})

// 方法
const resetTransform = () => {
  scale.value = 1
  rotation.value = 0
  translateX.value = 0
  translateY.value = 0
  loading.value = true
  error.value = false
}

const zoomIn = () => {
  if (scale.value < 3) {
    scale.value = Math.min(scale.value + 0.2, 3)
  }
}

const zoomOut = () => {
  if (scale.value > 0.2) {
    scale.value = Math.max(scale.value - 0.2, 0.2)
  }
}

const resetZoom = () => {
  scale.value = 1
  translateX.value = 0
  translateY.value = 0
}

const rotateLeft = () => {
  rotation.value -= 90
}

const rotateRight = () => {
  rotation.value += 90
}

const prevImage = () => {
  if (currentIndex.value > 0) {
    currentIndex.value--
  } else {
    currentIndex.value = props.images.length - 1
  }
}

const nextImage = () => {
  if (currentIndex.value < props.images.length - 1) {
    currentIndex.value++
  } else {
    currentIndex.value = 0
  }
}

const setCurrentImage = (index) => {
  currentIndex.value = index
}

const downloadImage = async () => {
  try {
    const response = await fetch(currentImage.value.url)
    const blob = await response.blob()
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = currentImage.value.title || `image-${currentIndex.value + 1}`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    ElMessage.success('图片下载成功')
  } catch (error) {
    ElMessage.error('图片下载失败')
  }
}

const handleImageLoad = () => {
  loading.value = false
  error.value = false
}

const handleImageError = () => {
  loading.value = false
  error.value = true
}

const handleClose = () => {
  visible.value = false
}

const handleKeydown = (event) => {
  switch (event.key) {
    case 'Escape':
      handleClose()
      break
    case 'ArrowLeft':
      prevImage()
      break
    case 'ArrowRight':
      nextImage()
      break
    case '+':
    case '=':
      zoomIn()
      break
    case '-':
      zoomOut()
      break
    case '0':
      resetZoom()
      break
  }
}

const startDrag = (event) => {
  if (scale.value <= 1) return
  
  isDragging.value = true
  dragStart.value = {
    x: event.clientX - translateX.value,
    y: event.clientY - translateY.value
  }
  
  document.addEventListener('mousemove', handleDrag)
  document.addEventListener('mouseup', endDrag)
}

const handleDrag = (event) => {
  if (!isDragging.value) return
  
  translateX.value = event.clientX - dragStart.value.x
  translateY.value = event.clientY - dragStart.value.y
}

const endDrag = () => {
  isDragging.value = false
  document.removeEventListener('mousemove', handleDrag)
  document.removeEventListener('mouseup', endDrag)
}
</script>

<style lang="scss" scoped>
.image-viewer-dialog {
  :deep(.el-dialog__body) {
    padding: 0;
    height: 100vh;
    overflow: hidden;
  }
}

.image-viewer-container {
  height: 100vh;
  background: rgba(0, 0, 0, 0.9);
  display: flex;
  flex-direction: column;
  color: white;
}

.image-viewer-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(10px);
  
  .image-info {
    display: flex;
    flex-direction: column;
    gap: 4px;
    
    .image-title {
      font-size: 16px;
      font-weight: 500;
    }
    
    .image-index {
      font-size: 14px;
      opacity: 0.7;
    }
  }
  
  .image-actions {
    display: flex;
    gap: 8px;
    
    .el-button {
      background: rgba(255, 255, 255, 0.1);
      border: 1px solid rgba(255, 255, 255, 0.2);
      color: white;
      
      &:hover {
        background: rgba(255, 255, 255, 0.2);
      }
    }
  }
}

.image-viewer-content {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}

.image-container {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  
  img {
    max-width: 90%;
    max-height: 90%;
    object-fit: contain;
    user-select: none;
  }
}

.image-loading,
.image-error {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  color: white;
  
  .loading-icon,
  .error-icon {
    font-size: 48px;
    opacity: 0.7;
  }
  
  .loading-icon {
    animation: spin 1s linear infinite;
  }
}

.nav-button {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 60px;
  height: 60px;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s ease;
  z-index: 10;
  
  &:hover {
    background: rgba(0, 0, 0, 0.7);
    transform: translateY(-50%) scale(1.1);
  }
  
  .el-icon {
    font-size: 24px;
    color: white;
  }
  
  &.nav-prev {
    left: 20px;
  }
  
  &.nav-next {
    right: 20px;
  }
}

.thumbnail-list {
  display: flex;
  justify-content: center;
  gap: 8px;
  padding: 20px;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(10px);
  overflow-x: auto;
  
  .thumbnail-item {
    width: 60px;
    height: 60px;
    border-radius: 6px;
    overflow: hidden;
    cursor: pointer;
    border: 2px solid transparent;
    transition: all 0.3s ease;
    flex-shrink: 0;
    
    &:hover {
      border-color: rgba(255, 255, 255, 0.5);
    }
    
    &.active {
      border-color: var(--el-color-primary);
    }
    
    img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
  }
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

@media (max-width: 768px) {
  .image-viewer-header {
    padding: 12px;
    
    .image-actions {
      gap: 4px;
      
      .el-button {
        width: 36px;
        height: 36px;
      }
    }
  }
  
  .nav-button {
    width: 48px;
    height: 48px;
    
    .el-icon {
      font-size: 20px;
    }
  }
  
  .thumbnail-list {
    padding: 12px;
    
    .thumbnail-item {
      width: 48px;
      height: 48px;
    }
  }
}
</style>
